package com.qiaofang.applet.service.other.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.common.context.QfContextHolder;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.service.other.domain.DictCorp;
import com.qiaofang.applet.service.other.domain.LendingRates;
import com.qiaofang.applet.service.other.repository.LendingRatesRepository;
import com.qiaofang.applet.service.other.service.LendingRatesService;
import com.qiaofang.applet.service.other.service.dto.LendingHistoricalDataDto;
import com.qiaofang.applet.service.other.service.dto.LendingRatesAdminDto;
import com.qiaofang.applet.service.other.service.dto.LendingRatesResultDto;
import com.qiaofang.applet.service.other.service.dto.TaxResultDto;
import com.qiaofang.applet.service.other.service.mapstruct.LendingRatesMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * @Author: youqing.yang
 * @Create: 2020/11/13 11:22
 * @Description:
 **/
@Slf4j
@Service
public class LendingRatesServiceImpl extends MongoBaseService<LendingRates, String> implements LendingRatesService {

    private final LendingRatesRepository repository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private LendingRatesMapper lendingRatesMapper;

    @Autowired
    public LendingRatesServiceImpl(LendingRatesRepository repository) {
        super(repository);
        this.repository = repository;
    }

    @Override
    public LendingRatesResultDto getLendingRates() {
        String corporationCode = QfContextHolder.getContext().getCorporationCode();
        Query query = new Query().addCriteria(Criteria.where("corporationCode").is(corporationCode));

        query.with(Sort.by(Sort.Order.desc("updateTime")));

        Optional<LendingRates> optional = Optional.ofNullable(mongoTemplate.find(query, LendingRates.class)).orElseGet(Lists::newArrayList)
                .stream().findFirst();
        if (!optional.isPresent()){
            throw new BusinessException("符合条件的利率不存在");
        }
        LendingRates lendingRates = optional.get();
        return lendingRatesMapper.domainToDto(lendingRates);
    }

    @Override
    public LendingRatesAdminDto getLendingRatesForAdmin(String corporationCode) {
        Query query = new Query().addCriteria(Criteria.where("corporationCode").is(corporationCode));
        query.with(Sort.by(Sort.Order.desc("updateTime")));
        Optional<LendingRates> optional = Optional.ofNullable(mongoTemplate.find(query, LendingRates.class)).orElseGet(Lists::newArrayList)
                .stream().findFirst();
        if (!optional.isPresent()){
            throw new BusinessException("符合条件的利率不存在");
        }
        log.info("getLendingRatesForAdmin:{}", optional.get());
        return lendingRatesMapper.domainToAdminDto(optional.get());
    }

    @Override
    public void saveLendingRates(LendingRates lendingRates) {
        if (StringUtils.isBlank(lendingRates.getId())){
            lendingRates.setId(ObjectId.get().toString());
            List<LendingHistoricalDataDto> lendingHistoricalDataDtos = listHistoricalData(lendingRates.getCorporationCode());
            for (LendingHistoricalDataDto lendingHistoricalDataDto : lendingHistoricalDataDtos) {
                if (DateUtils.isSameDay(lendingHistoricalDataDto.getLprPublishDate(),lendingRates.getLprPublishDate())){
                    throw new BusinessException("LPR发布时间重复，请选择其他日期");
                }
            }
            repository.save(lendingRates);
        } else {
            updateById(lendingRates);
        }
    }

    @Override
    public String totalCount(TaxResultDto taxResultDto) {
        Double deedTax;
        if (StringUtils.isNotBlank(taxResultDto.getDeedTax())){
            deedTax = Double.valueOf(taxResultDto.getDeedTax());
        } else {
            deedTax = 0.00;
        }
        Double addedTax;
        if (StringUtils.isNotBlank(taxResultDto.getAddedTax())){
            addedTax = Double.valueOf(taxResultDto.getAddedTax());
        } else {
            addedTax = 0.00;
        }
        Double incomeTax;
        if (StringUtils.isNotBlank(taxResultDto.getIncomeTax())){
            incomeTax = Double.valueOf(taxResultDto.getIncomeTax());
        } else {
            incomeTax = 0.00;
        }
        Double educationTax;
        if (StringUtils.isNotBlank(taxResultDto.getEducationTax())){
            educationTax = Double.valueOf(taxResultDto.getEducationTax());
        } else {
            educationTax = 0.00;
        }
        Double maintainTax;
        if (StringUtils.isNotBlank(taxResultDto.getMaintainTax())){
            maintainTax = Double.valueOf(taxResultDto.getMaintainTax());
        } else {
            maintainTax = 0.00;
        }
        Double landAddedTax;
        if (StringUtils.isNotBlank(taxResultDto.getLandAddedTax())){
            landAddedTax = Double.valueOf(taxResultDto.getLandAddedTax());
        } else {
            landAddedTax = 0.00;
        }
        Double printingTax;
        if (StringUtils.isNotBlank(taxResultDto.getPrintingTax())){
            printingTax = Double.valueOf(taxResultDto.getPrintingTax());
        } else {
            printingTax = 0.00;
        }
        Double assignTax;
        if (StringUtils.isNotBlank(taxResultDto.getAssignTax())){
            assignTax = Double.valueOf(taxResultDto.getAssignTax());
        } else {
            assignTax = 0.00;
        }
        Double total = deedTax + addedTax + incomeTax + educationTax + maintainTax + landAddedTax + printingTax + assignTax;
        DecimalFormat df = new DecimalFormat("#0.00");
        return df.format(total);
    }

    @Override
    public List<LendingHistoricalDataDto> listHistoricalData(String corporationCode) {
        List<LendingHistoricalDataDto> collectList = null;
        try {
            Query query = new Query().addCriteria(Criteria.where("corporationCode").is(corporationCode));
            query.with(Sort.by(Sort.Order.desc("lprPublishDate")));
            List<LendingRates> lendingRates = mongoTemplate.find(query, LendingRates.class);
            collectList = Optional.ofNullable(lendingRates).orElseGet(Lists::newArrayList)
                    .stream().map(lendingRatesMapper::domainToDtoForAdmin).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查看历史lpr数据异常 {}:", e);
        }
        return collectList;
    }

    @Override
    public void initLendingRates(String corporationCode) {
        // 判断如果已经存在房贷利率数据，则不进行初始化
        List<LendingHistoricalDataDto> list = listHistoricalData(corporationCode);
        if(!CollectionUtils.isEmpty(list)) {
            return;
        }
        try {
            ClassPathResource resource = new ClassPathResource("corporation/initLendingRates.json");
            String initStr = IOUtils.toString(resource.getInputStream(), "UTF-8");
            List<LendingRates> datas = JSON.parseArray(initStr, LendingRates.class);
            datas.parallelStream().forEach(data ->{
                data.setCorporationCode(corporationCode);
            });
            repository.saveAll(datas);
        } catch (Exception e) {
            log.error("初始化集团房贷利率异常,corporationCode:{}", e);
            throw new BusinessException("初始化集团房贷利率异常");
        }
    }
}
